package com.ittao.taoaicodemother.manage.upload;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;

import com.ittao.taoaicodemother.config.CosClientConfig;
import com.ittao.taoaicodemother.exception.BusinessException;
import com.ittao.taoaicodemother.exception.ErrorCode;
import com.ittao.taoaicodemother.manage.cos.CosManager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;

/**
 * 图片上传模板方法（模板方法设计模式）
 */
@Slf4j
@Service
public abstract class PictureUploadTemplate {

    @Resource
    private CosClientConfig cosClientConfig;

    @Resource
    private CosManager cosManager;

    /**
     * 上传图片
     *
     * @param inputSource      上传的文件
     * @param uploadPathPrefix 上传路径前缀
     * @return 图片上传地址
     */
    public String uploadPicture(Object inputSource, String uploadPathPrefix) {
        // 1. 校验图片
        validPicture(inputSource);
        // 2. 图片上传地址
        String uuid = RandomUtil.randomString(16);
        // 获取原始文件名
        String originalFilename = getOriginFilename(inputSource);
        // 自己拼接文件上传路径，而不是使用原始文件名称，可以增强安全性
        String uploadFileName = String.format("%s_%s.%s", DateUtil.formatDate(new Date()),
                uuid,
                (Objects.equals(FileUtil.getSuffix(originalFilename), "")
                        ? "png" : FileUtil.getSuffix(originalFilename)));
        String uploadPath = String.format("%s/%s", uploadPathPrefix, uploadFileName);
        // 解析结果并返回
        File file = null;
        try {
            // 3. 创建临时文件，上传文件到服务器
            file = File.createTempFile(uploadPath, null);
            // 处理文件来源
            processFile(inputSource, file);
            // 4. 上传到腾讯云COS
            cosManager.putPictureObject(uploadPath, file);
            // 5. 返回图片地址
            return cosClientConfig.getHost() + "/" + uploadPath;
        } catch (IOException e) {
            log.error("文件上传失败,filePath = {}", uploadPath, e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件上传失败，请稍后重试");
        } finally {
            // 临时文件清理
            deleteTempFile(file);
        }
    }

    /**
     * 校验图片
     *
     * @param inputSource
     */
    protected abstract void validPicture(Object inputSource);

    /**
     * 获取原始文件名
     *
     * @param inputSource 上传的文件
     * @return 原始文件名
     */
    protected abstract String getOriginFilename(Object inputSource);

    /**
     * 处理文件来源
     *
     * @param inputSource 上传的文件
     * @param file
     */
    protected abstract void processFile(Object inputSource, File file) throws IOException;

    /**
     * 删除临时文件
     *
     * @param file 临时文件
     */
    private static void deleteTempFile(File file) {
        if (file != null) {
            // 删除临时文件
            if (!file.delete()) {
                log.warn("临时文件删除失败，filePath = {}", file.getAbsolutePath());
            }
        }
    }
}
